package com.peanut.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.peanut.dao.PeanutDao;
import com.peanut.dto.TabItemDTO;
import com.peanut.entity.TabItem;
import com.peanut.service.TabItemService;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2022-05-27
 */
@Service
public class TabItemServiceImpl  implements TabItemService {

    @Resource
    private RestHighLevelClient client;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private PeanutDao peanutDao;

    @Override
    public Map<String, Object> selectInfo(String title, Integer pageNum, Integer pageSize) {
        //这里写从es中查询的条件
        //设置请求的对象,设置查询的索引库
        SearchRequest request = new SearchRequest("tab_item");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //这个是精确模糊搜索
        MatchPhraseQueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("item_name", title);
        searchSourceBuilder.query(queryBuilder);

        //设置高亮的字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("item_name");
        //设置高亮的样式
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");

        //将高亮放入请求中
        searchSourceBuilder.highlighter(highlightBuilder);

        //设置分页
        searchSourceBuilder.from((pageNum-1) * pageSize);
        searchSourceBuilder.size(pageSize);

        //将所有的请求放入request中
        request.source(searchSourceBuilder);

        //准备数据
        List<TabItem> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        long totalHits = 0;

        try {
            //调用方法进行通讯
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //获取结果
            SearchHit[] hits = response.getHits().getHits();
            //获取总条数
            totalHits = response.getHits().getTotalHits().value;

            //循环遍历
            for (SearchHit hit : hits) {
                //获取普通内容
                String sourceAsString = hit.getSourceAsString();
                //将普通内容转换成实体类类型
                TabItem tabItem = JSONObject.parseObject(sourceAsString, TabItem.class);
                //获取高亮的字段
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                //解析高亮的结果
                HighlightField highlightField = highlightFields.get("item_name");
                Text[] fragments = highlightField.getFragments();
                for (Text fragment : fragments) {
                    //获取高亮的字段并且set给实体类
                    tabItem.setItemName(fragment.toString());
                }
                list.add(tabItem);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        map.put("list",list);
        map.put("total",totalHits);
        return map;
    }

    @Override
    public Map<String, Object> selectCondition(Date itemRegisteredDate, Long itemRoadHaul, String itemEvaluate,
                                               String itemValidate, Integer itemEmissionStandard, Integer itemCity,
                                               BigDecimal itemPrice, BigDecimal itemNewPrice, Integer itemChangeNumber,
                                               BigDecimal itemDisplacement, Date itemAnnualInspectionDate,
                                               String itemFunction, Date itemMliftaDate, Integer itemColor,
                                               Date itemProductionDate, Long itemOptions, Integer itemKeyNum,
                                               Integer itemRank, Integer itemSeating, Long itemCarAge,
                                               Integer itemLocationLicensePlate, Integer itemEnergySources,
                                               Integer itemGearbox, Integer itemAirCylinder, Integer itemAirInlet,
                                               Integer itemDrivingType, Integer itemContry, Integer itemYearType,
                                               Long itemHits) {
        SearchRequest request = new SearchRequest("tab_item");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (itemRegisteredDate != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_registered_date",itemRegisteredDate));
        }else if (itemRoadHaul != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_road_haul",itemRoadHaul));
        }else if (itemEvaluate != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_evaluate",itemEvaluate));
        }else if (itemValidate != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_validate",itemValidate));
        }else if (itemEmissionStandard != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_emission_standard",itemEmissionStandard));
        }else if (itemCity != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_city",itemCity));
        }else if (itemPrice != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_price",itemPrice));
        }else if (itemNewPrice != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_new_price",itemNewPrice));
        }else if (itemChangeNumber != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_change_number",itemChangeNumber));
        }else if (itemDisplacement != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_displacement",itemDisplacement));
        }else if (itemAnnualInspectionDate != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_annual_inspection_date",itemAnnualInspectionDate));
        }else if (itemFunction != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_function",itemFunction));
        }else if (itemMliftaDate != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_mlifta_date",itemMliftaDate));
        }else if (itemColor != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_color",itemColor));
        }else if (itemProductionDate != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_production_date",itemProductionDate));
        }else if (itemOptions != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_options",itemOptions));
        }else if (itemKeyNum != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_key_num",itemKeyNum));
        }else if (itemRank != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_rank",itemRank));
        }else if (itemSeating != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_seating",itemSeating));
        }else if (itemCarAge != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_car_age",itemCarAge));
        }else if (itemLocationLicensePlate != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_location_license_plate",itemLocationLicensePlate));
        }else if (itemEnergySources != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_energy_sources",itemEnergySources));
        }else if (itemGearbox != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_gearbox",itemGearbox));
        }else if (itemAirCylinder != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_air_cylinder",itemAirCylinder));
        }else if (itemAirInlet != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_air_inlet",itemAirInlet));
        }else if (itemDrivingType != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_driving_type",itemDrivingType));
        }else if (itemContry != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_contry",itemContry));
        }else if (itemYearType != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_year_type",itemYearType));
        }else if (itemHits != null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("item_hits",itemHits));
        }
        searchSourceBuilder.query(boolQueryBuilder);

        //将所有的请求放入request中
        request.source(searchSourceBuilder);

        List<TabItem> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        long totalHits = 0;

        try {

            //调用方法进行通讯
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //获取结果
            SearchHit[] hits = response.getHits().getHits();
            //获取总条数
            totalHits = response.getHits().getTotalHits().value;

            for (SearchHit hit : hits) {
                //获取普通内容
                String sourceAsString = hit.getSourceAsString();
                //将普通内容转换成实体类类型
                TabItem tabItem = JSONObject.parseObject(sourceAsString, TabItem.class);
                list.add(tabItem);
            };

        }catch (Exception e){
            e.printStackTrace();
        }
        map.put("list",list);
        map.put("total",totalHits);
        //返回结果
        return map;
    }

    @Override
    public boolean test() {
        boolean b = elasticsearchRestTemplate.indexOps(TabItemDTO.class).exists();
        System.out.println("索引"+(b?"存在":"不存在"));
        return b;
    }
}
